home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / nethack.lha / nethack-3.1 / src / priest.c < prev    next >
C/C++ Source or Header  |  1992-12-29  |  17KB  |  640 lines

  1. /*    SCCS Id: @(#)priest.c    3.1    92/01/05
  2. /* Copyright (c) Izchak Miller, Steve Linhart, 1989.           */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include "hack.h"
  6. #include "mfndpos.h"
  7. #include "eshk.h"
  8. #include "epri.h"
  9. #include "emin.h"
  10.  
  11. #ifdef OVLB
  12.  
  13. static boolean FDECL(histemple_at,(struct monst *,XCHAR_P,XCHAR_P));
  14. static boolean FDECL(has_shrine,(struct monst *));
  15.  
  16. /*
  17.  * Move for priests and shopkeepers.  Called from shk_move() and pri_move().
  18.  * Valid returns are  1: moved  0: didn't  -1: let m_move do it  -2: died.
  19.  */
  20. int
  21. move_special(mtmp,in_his_shop,appr,uondoor,avoid,omx,omy,gx,gy)
  22. register struct monst *mtmp;
  23. boolean in_his_shop;
  24. schar appr;
  25. boolean uondoor,avoid;
  26. register xchar omx,omy,gx,gy;
  27. {
  28.     register xchar nx,ny,nix,niy;
  29.     register schar i;
  30.     schar chcnt,cnt;
  31.     coord poss[9];
  32.     long info[9];
  33.     long allowflags;
  34.     struct obj *ib = (struct obj *)0;
  35.  
  36.     if(omx == gx && omy == gy)
  37.         return(0);
  38.     if(mtmp->mconf) {
  39.         avoid = FALSE;
  40.         appr = 0;
  41.     }
  42.  
  43.     nix = omx;
  44.     niy = omy;
  45.     if (mtmp->isshk) allowflags = ALLOW_SSM;
  46.     else allowflags = ALLOW_SSM | ALLOW_SANCT;
  47.     if (passes_walls(mtmp->data)) allowflags |= (ALLOW_ROCK|ALLOW_WALL);
  48.     if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
  49.     if (tunnels(mtmp->data) &&
  50.             (!needspick(mtmp->data) || m_carrying(mtmp, PICK_AXE)))
  51.         allowflags |= ALLOW_DIG;
  52.     if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
  53.         allowflags |= OPENDOOR;
  54.         if (m_carrying(mtmp, SKELETON_KEY)) allowflags |= BUSTDOOR;
  55.     }
  56.     if (is_giant(mtmp->data)) allowflags |= BUSTDOOR;
  57.     cnt = mfndpos(mtmp, poss, info, allowflags);
  58.  
  59.     if(mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
  60.         for(i=0; i<cnt; i++)
  61.             if(!(info[i] & NOTONL)) goto pick_move;
  62.         avoid = FALSE;
  63.     }
  64.  
  65. #define    GDIST(x,y)    (dist2(x,y,gx,gy))
  66. pick_move:
  67.     chcnt = 0;
  68.     for(i=0; i<cnt; i++) {
  69.         nx = poss[i].x;
  70.         ny = poss[i].y;
  71.         if(levl[nx][ny].typ == ROOM ||
  72.             (mtmp->ispriest &&
  73.                 levl[nx][ny].typ == ALTAR) ||
  74.             (mtmp->isshk &&
  75.                 (!in_his_shop || ESHK(mtmp)->following))) {
  76.             if(avoid && (info[i] & NOTONL))
  77.             continue;
  78.             if((!appr && !rn2(++chcnt)) ||
  79.             (appr && GDIST(nx,ny) < GDIST(nix,niy))) {
  80.                 nix = nx;
  81.                 niy = ny;
  82.             }
  83.         }
  84.     }
  85.     if(mtmp->ispriest && avoid &&
  86.             nix == omx && niy == omy && onlineu(omx,omy)) {
  87.         /* might as well move closer as long it's going to stay
  88.          * lined up */
  89.         avoid = FALSE;
  90.         goto pick_move;
  91.     }
  92.  
  93.     if(nix != omx || niy != omy) {
  94.         remove_monster(omx, omy);
  95.         place_monster(mtmp, nix, niy);
  96.         newsym(nix,niy);
  97.         if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
  98.             check_special_room(FALSE);
  99.         if(ib) {
  100.             if (cansee(mtmp->mx,mtmp->my))
  101.                 pline("%s picks up %s.", Monnam(mtmp),
  102.                 distant_name(ib,doname));
  103.             freeobj(ib);
  104.             mpickobj(mtmp, ib);
  105.         }
  106.         return(1);
  107.     }
  108.     return(0);
  109. }
  110.  
  111. #endif /* OVLB */
  112.  
  113. #ifdef OVL0
  114.  
  115. char
  116. temple_occupied(array)
  117. register char *array;
  118. {
  119.     register char *ptr;
  120.  
  121.     for (ptr = array; *ptr; ptr++)
  122.         if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
  123.             return(*ptr);
  124.     return('\0');
  125. }
  126.  
  127. #endif /* OVL0 */
  128. #ifdef OVLB
  129.  
  130. static boolean
  131. histemple_at(priest, x, y)
  132. register struct monst *priest;
  133. register xchar x, y;
  134. {
  135.     return((EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE)) &&
  136.            on_level(&(EPRI(priest)->shrlevel), &u.uz));
  137. }
  138.  
  139. /*
  140.  * pri_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
  141.  */
  142. int
  143. pri_move(priest)
  144. register struct monst *priest;
  145. {
  146.     register xchar gx,gy,omx,omy;
  147.     schar temple;
  148.     boolean avoid = TRUE;
  149.  
  150.     omx = priest->mx;
  151.     omy = priest->my;
  152.  
  153.     if(!histemple_at(priest, omx, omy)) return(-1);
  154.  
  155.     temple = EPRI(priest)->shroom;
  156.  
  157.     gx = EPRI(priest)->shrpos.x;
  158.     gy = EPRI(priest)->shrpos.y;
  159.  
  160.     gx += rn1(3,-1);    /* mill around the altar */
  161.     gy += rn1(3,-1);
  162.  
  163.     if(!priest->mpeaceful ||
  164.        (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
  165.         if(monnear(priest, u.ux, u.uy)) {
  166.             if(Displaced)
  167.                 Your("displaced image doesn't fool %s!",
  168.                     mon_nam(priest));
  169.             (void) mattacku(priest);
  170.             return(0);
  171.         } else if(index(u.urooms, temple)) {
  172.             /* chase player if inside temple & can see him */
  173.             if(priest->mcansee && m_canseeu(priest)) {
  174.                 gx = u.ux;
  175.                 gy = u.uy;
  176.             }
  177.             avoid = FALSE;
  178.         }
  179.     } else if(Invis) avoid = FALSE;
  180.  
  181.     return(move_special(priest,FALSE,TRUE,FALSE,avoid,omx,omy,gx,gy));
  182. }
  183.  
  184. /* exclusively for mktemple() */
  185. void
  186. priestini(lvl, sroom, sx, sy, sanctum)
  187. d_level    *lvl;
  188. struct mkroom *sroom;
  189. int sx, sy;
  190. boolean sanctum;   /* is it the seat of the high priest? */
  191. {
  192.     register struct monst *priest;
  193.     register struct obj *otmp;
  194.     register int cnt;
  195.  
  196.     if(MON_AT(sx+1, sy))
  197.         rloc(m_at(sx+1, sy)); /* insurance */
  198.  
  199.     if(priest = (sanctum ? makemon(&mons[PM_HIGH_PRIEST], sx+1, sy)
  200.                  : makemon(&mons[PM_ALIGNED_PRIEST], sx+1, sy))) {
  201.         EPRI(priest)->shroom = (sroom - rooms) + ROOMOFFSET;
  202.         EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask);
  203.         EPRI(priest)->shrpos.x = sx;
  204.         EPRI(priest)->shrpos.y = sy;
  205.         assign_level(&(EPRI(priest)->shrlevel), lvl);
  206.         priest->mtrapseen = ~0;    /* traps are known */
  207.         priest->mpeaceful = 1;
  208.         priest->ispriest = 1;
  209.         priest->msleep = 0;
  210.         set_malign(priest); /* mpeaceful may have changed */
  211.  
  212.         /* now his/her goodies... */
  213.         (void) mongets(priest, CHAIN_MAIL);
  214.         (void) mongets(priest, SMALL_SHIELD);
  215. #ifdef MUSE
  216.         m_dowear(priest, TRUE);
  217. #endif
  218.         priest->mgold = (long)rn1(10,20);
  219.         if(sanctum && EPRI(priest)->shralign == A_NONE &&
  220.              on_level(&sanctum_level, &u.uz))
  221.             (void) mongets(priest, AMULET_OF_YENDOR);
  222.         /* Do NOT put the rest in m_initinv.    */
  223.         /* Priests created elsewhere than in a  */
  224.         /* temple should not carry these items, */
  225.         /* except for the mace.            */
  226.         cnt = rn1(2,3);
  227.         while(cnt) {
  228.             otmp = mkobj(SPBOOK_CLASS, FALSE);
  229.             if(otmp) mpickobj(priest, otmp);
  230.             cnt--;
  231.         }
  232.         if(p_coaligned(priest))
  233.             (void) mongets(priest, rn2(2) ? CLOAK_OF_PROTECTION
  234.                           : CLOAK_OF_MAGIC_RESISTANCE);
  235.         else {
  236.             if(!rn2(5))
  237.             otmp = mksobj(CLOAK_OF_MAGIC_RESISTANCE, TRUE, FALSE);
  238.             else otmp = mksobj(CLOAK_OF_PROTECTION, TRUE, FALSE);
  239.             if(otmp) {
  240.             if(!rn2(2)) curse(otmp);
  241.             mpickobj(priest, otmp);
  242.             }
  243.         }
  244.  
  245.         otmp = mksobj(MACE, FALSE, FALSE);
  246.         if(otmp) {
  247.             otmp->spe = rnd(3);
  248.             if(!rn2(2)) curse(otmp);
  249.             mpickobj(priest, otmp);
  250.         }
  251.     }
  252. }
  253.  
  254. /*
  255.  * Specially aligned monsters are named specially.
  256.  *    - aligned priests with ispriest and high priests have shrines
  257.  *        they retain ispriest and epri when polymorphed
  258.  *    - aligned priests without ispriest and Angels are roamers
  259.  *        they retain isminion and access epri as emin when polymorphed
  260.  *        (coaligned Angels are also created as minions, but they
  261.  *        use the same naming convention)
  262.  *    - minions do not have ispriest but have isminion and emin
  263.  */
  264. char *
  265. priestname(mon)
  266. register struct monst *mon;
  267. {
  268.     static char NEARDATA pname[PL_NSIZ];
  269.  
  270.     Strcpy(pname, "the ");
  271.     if (mon->minvis) Strcat(pname, "invisible ");
  272.     if (mon->ispriest || mon->data == &mons[PM_ALIGNED_PRIEST] ||
  273.                     mon->data == &mons[PM_ANGEL]) {
  274.         /* use epri */
  275.         if (mon->mtame && mon->data == &mons[PM_ANGEL])
  276.             Strcat(pname, "guardian ");
  277.         if (mon->data != &mons[PM_ALIGNED_PRIEST] &&
  278.                 mon->data != &mons[PM_HIGH_PRIEST]) {
  279.             Strcat(pname, mon->data->mname);
  280.             Strcat(pname, " ");
  281.         }
  282.         if (mon->data != &mons[PM_ANGEL]) {
  283.             if (!mon->ispriest && EPRI(mon)->renegade)
  284.                 Strcat(pname, "renegade ");
  285.             if (mon->data == &mons[PM_HIGH_PRIEST])
  286.                 Strcat(pname, "high ");
  287.             if (mon->female)
  288.                 Strcat(pname, "priestess ");
  289.             else
  290.                 Strcat(pname, "priest ");
  291.         }
  292.         Strcat(pname, "of ");
  293.         Strcat(pname, align_gname((int)EPRI(mon)->shralign));
  294.         return(pname);
  295.     }
  296.     /* use emin instead of epri */
  297.     Strcat(pname, mon->data->mname);
  298.     Strcat(pname, " of ");
  299.     Strcat(pname, align_gname(EMIN(mon)->min_align));
  300.     return(pname);
  301. }
  302.  
  303. boolean
  304. p_coaligned(priest)
  305. struct monst *priest;
  306. {
  307.     return(u.ualign.type == ((int)EPRI(priest)->shralign));
  308. }
  309.  
  310. static boolean
  311. has_shrine(pri)
  312. struct monst *pri;
  313. {
  314.     struct rm *lev;
  315.  
  316.     if(!pri)
  317.         return(FALSE);
  318.     lev = &levl[EPRI(pri)->shrpos.x][EPRI(pri)->shrpos.y];
  319.     if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
  320.         return(FALSE);
  321.     return(EPRI(pri)->shralign == Amask2align(lev->altarmask & ~AM_SHRINE));
  322. }
  323.  
  324. struct monst *
  325. findpriest(roomno)
  326. char roomno;
  327. {
  328.     register struct monst *mtmp;
  329.     extern struct monst *fdmon; /* from mon.c */
  330.  
  331.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  332.         if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
  333.            histemple_at(mtmp,mtmp->mx,mtmp->my))
  334.         return(mtmp);
  335.     for(mtmp = fdmon; mtmp; mtmp = mtmp->nmon)
  336.         if(mtmp->ispriest && (EPRI(mtmp)->shroom == roomno) &&
  337.            histemple_at(mtmp,mtmp->mx,mtmp->my))
  338.         return(mtmp);
  339.     return (struct monst *)0;
  340. }
  341.  
  342. /* called from check_special_room() when the player enters the temple room */
  343. void
  344. intemple(roomno)
  345. register int roomno;
  346. {
  347.     register struct monst *priest = findpriest((char)roomno);
  348.     boolean tended = (priest != (struct monst *)0);
  349.     boolean shrined = (tended && has_shrine(priest));
  350.     boolean sanctum = (tended && priest->data == &mons[PM_HIGH_PRIEST] &&
  351.                 (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
  352.  
  353.     if(!temple_occupied(u.urooms0)) {
  354.         if(tended) {
  355.         pline("%s intones:",
  356.               (!Blind ? Monnam(priest) : "A nearby voice"));
  357.         if(sanctum && Is_sanctum(&u.uz)) {
  358.             if(priest->mpeaceful) {
  359.               verbalize("Infidel, you entered Moloch's Sanctum!");
  360.               verbalize("Be gone!");
  361.               priest->mpeaceful = 0;
  362.               set_malign(priest);
  363.             } else
  364.               verbalize("You desecrate this place by your presence!");
  365.         } else verbalize("Pilgrim, you enter a%s place!",
  366.                !shrined ? " desecrated" :
  367.                " sacred");
  368.         if(!sanctum) {
  369.             /* !tended -> !shrined */
  370.             if(!shrined || !p_coaligned(priest) ||
  371.                            u.ualign.record < -5)
  372.             You("have a%s forbidding feeling...",
  373.                 (!shrined) ? "" : " strange");
  374.             else You("experience a strange sense of peace.");
  375.         }
  376.         } else {
  377.         switch(rn2(3)) {
  378.           case 0: You("have an eerie feeling..."); break;
  379.           case 1: You("feel like you are being watched."); break;
  380.           default: pline("A shiver runs down your spine."); break;
  381.         }
  382.         if(!rn2(5)) {
  383.             struct monst *mtmp;
  384.  
  385.             if(!(mtmp = makemon(&mons[PM_GHOST],u.ux,u.uy))) return;
  386.             pline("An enormous ghost appears next to you!");
  387.             mtmp->mpeaceful = 0;
  388.             set_malign(mtmp);
  389.             if(flags.verbose)
  390.             You("are frightened to death, and unable to move.");
  391.             nomul(-3);
  392.             nomovemsg = "You regain your composure.";
  393.            }
  394.        }
  395.        }
  396. }
  397.  
  398. void
  399. priest_talk(priest)
  400. register struct monst *priest;
  401. {
  402.     boolean coaligned = p_coaligned(priest);
  403.     boolean strayed = (u.ualign.record < 0);
  404.  
  405.     if(priest->mflee || (!priest->ispriest && coaligned && strayed)) {
  406.         pline("%s doesn't want anything to do with you!",
  407.                 Monnam(priest));
  408.         priest->mpeaceful = 0;
  409.         return;
  410.     }
  411.  
  412.     /* priests don't chat unless peaceful and in their own temple */
  413.     if(!histemple_at(priest,priest->mx,priest->my) ||
  414.          !priest->mpeaceful || !priest->mcanmove || priest->msleep) {
  415.         if(!priest->mcanmove || priest->msleep) {
  416.         pline("%s breaks out of %s reverie!",
  417.             humanoid(priest->data)
  418.                 ? (priest->female ? "her" : "his")
  419.                 : "its",
  420.             Monnam(priest));
  421.         priest->mfrozen = priest->msleep = 0;
  422.         priest->mcanmove = 1;
  423.         }
  424.         priest->mpeaceful = 0;
  425.         switch(rn2(3)) {
  426.         case 0:
  427.            verbalize("Thou wouldst have words, eh?  I'll give thee a word or two!");
  428.            break;
  429.         case 1:
  430.            verbalize("Talk?  Here is what I have to say!");
  431.            break;
  432.         default:
  433.            verbalize("Pilgrim, I have lost mine desire to talk.");
  434.            break;
  435.         }
  436.         return;
  437.     }
  438.  
  439.     /* you desecrated the temple and now you want to chat? */
  440.     if(priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE) &&
  441.           !has_shrine(priest)) {
  442.         verbalize("Begone!  Thou desecratest this holy place with thy presence.");
  443.         priest->mpeaceful = 0;
  444.         return;
  445.     }
  446.  
  447.     if(!u.ugold) {
  448.         if(coaligned && !strayed) {
  449.         if (priest->mgold > 0L) {
  450.             /* Note: two bits is actually 25 cents.  Hmm. */
  451.             pline("%s gives you %s for an ale.", Monnam(priest),
  452.             (priest->mgold == 1L) ? "one bit" : "two bits");
  453.             if (priest->mgold > 1L)
  454.             u.ugold = 2L;
  455.             else
  456.             u.ugold = 1L;
  457.             priest->mgold -= u.ugold;
  458.             flags.botl = 1;
  459.         } else
  460.             pline("%s preaches the virtues of poverty.", Monnam(priest));
  461.         exercise(A_WIS, TRUE);
  462.         } else
  463.         pline("%s is not interested.", Monnam(priest));
  464.         return;
  465.     } else {
  466.         long offer;
  467.  
  468.         pline("%s asks you for a contribution for the temple.",
  469.             Monnam(priest));
  470.         if((offer = bribe(priest)) == 0) {
  471.         verbalize("Thou shalt regret thine action!");
  472.         if(coaligned) u.ualign.record--;
  473.         } else if(offer < (u.ulevel * 200)) {
  474.         if(u.ugold > (offer * 2L)) verbalize("Cheapskate.");
  475.         else {
  476.             verbalize("I thank thee for thy contribution.");
  477.             /*  give player some token  */
  478.             exercise(A_WIS, TRUE);
  479.         }
  480.         } else if(offer < (u.ulevel * 400)) {
  481.         verbalize("Thou art indeed a pious individual.");
  482.         if(u.ugold < (offer * 2L)) {
  483.             if(coaligned && u.ualign.record < -5) u.ualign.record++;
  484.             verbalize("I bestow upon thee a blessing.");
  485.             Clairvoyant += rn1(500,500);
  486.         }
  487.         } else if(offer < (u.ulevel * 600)) {
  488.         verbalize("Thy devotion has been rewarded.");
  489.         if (!(Protection & INTRINSIC))  {
  490.             Protection |= FROMOUTSIDE;
  491.             if (!u.ublessed)  u.ublessed = rn1(3, 2);
  492.         } else u.ublessed++;
  493.         } else {
  494.         verbalize("Thy selfless generosity is deeply appreciated.");
  495.         if(u.ugold < (offer * 2L) && coaligned) {
  496.             if(strayed && (moves - u.ucleansed) > 5000L) {
  497.             u.ualign.record = 0; /* cleanse him */
  498.             u.ucleansed = moves;
  499.             } else {
  500.             u.ualign.record += 2;
  501.             }
  502.         }
  503.         }
  504.     }
  505. }
  506.  
  507. struct monst *
  508. mk_roamer(ptr, alignment, x, y, peaceful)
  509. register struct permonst *ptr;
  510. aligntyp alignment;
  511. xchar x, y;
  512. boolean peaceful;
  513. {
  514.     register struct monst *roamer;
  515.     register boolean coaligned = (u.ualign.type == alignment);
  516.  
  517.     if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
  518.         return((struct monst *)0);
  519.     
  520.     if (MON_AT(x, y)) rloc(m_at(x, y));    /* insurance */
  521.  
  522.     if (!(roamer = makemon(ptr, x, y)))
  523.         return((struct monst *)0);
  524.  
  525.     EPRI(roamer)->shralign = alignment;
  526.     if (coaligned && !peaceful)
  527.         EPRI(roamer)->renegade = TRUE;
  528.     /* roamer->ispriest == FALSE naturally */
  529.     roamer->isminion = TRUE;    /* borrowing this bit */
  530.     roamer->mtrapseen = ~0;        /* traps are known */
  531.     roamer->mpeaceful = peaceful;
  532.     roamer->msleep = 0;
  533.     set_malign(roamer); /* peaceful may have changed */
  534.  
  535.     /* MORE TO COME */
  536.     return(roamer);
  537. }
  538.  
  539. void
  540. reset_hostility(roamer)
  541. register struct monst *roamer;
  542. {
  543.         if(!(roamer->isminion && (roamer->data == &mons[PM_ALIGNED_PRIEST] ||
  544.                   roamer->data == &mons[PM_ANGEL])))
  545.             return;
  546.  
  547.         if(EPRI(roamer)->shralign != u.ualign.type) {
  548.         roamer->mpeaceful = roamer->mtame = 0;
  549.         set_malign(roamer);
  550.     }
  551.     newsym(roamer->mx, roamer->my);
  552. }
  553.  
  554. boolean
  555. in_your_sanctuary(x, y)
  556. xchar x, y;
  557. {
  558.     register char roomno;
  559.     register struct monst *priest;
  560.  
  561.     if ((u.ualign.record < -5) || !(roomno = temple_occupied(u.urooms)) ||
  562.         (roomno != *in_rooms(x, y, TEMPLE)) ||
  563.         !(priest = findpriest(roomno)))
  564.         return(FALSE);
  565.     return(has_shrine(priest) && p_coaligned(priest) && priest->mpeaceful);
  566. }
  567.  
  568. void
  569. ghod_hitsu(priest)     /* when attacking "priest" in his temple */
  570. struct monst *priest;
  571. {
  572.     int x, y, ax, ay, roomno = (int)temple_occupied(u.urooms);
  573.     struct mkroom *troom;
  574.  
  575.     if (!roomno || !has_shrine(priest))
  576.         return;
  577.  
  578.     ax = x = EPRI(priest)->shrpos.x;
  579.     ay = y = EPRI(priest)->shrpos.y;
  580.     troom = &rooms[roomno - ROOMOFFSET];
  581.  
  582.     if((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y)) {
  583.         if(IS_DOOR(levl[u.ux][u.uy].typ)) {
  584.  
  585.         if(u.ux == troom->lx - 1) {
  586.             x = troom->hx;
  587.             y = u.uy;
  588.         } else if(u.ux == troom->hx + 1) {
  589.             x = troom->lx;
  590.             y = u.uy;
  591.         } else if(u.uy == troom->ly - 1) {
  592.             x = u.ux;
  593.             y = troom->hy;
  594.         } else if(u.uy == troom->hy + 1) {
  595.             x = u.ux;
  596.             y = troom->ly;
  597.         }
  598.         } else {
  599.         switch(rn2(4)) {
  600.         case 0:  x = u.ux; y = troom->ly; break;
  601.         case 1:  x = u.ux; y = troom->hy; break;
  602.         case 2:  x = troom->lx; y = u.uy; break;
  603.         default: x = troom->hx; y = u.uy; break;
  604.         }
  605.         }
  606.         if(!linedup(u.ux, u.uy, x, y)) return;
  607.     }
  608.  
  609.     switch(rn2(3)) {
  610.     case 0:
  611.         pline("%s roars in anger:  \"Thou shalt suffer!\"",
  612.             a_gname_at(ax, ay));
  613.         break;
  614.     case 1:
  615.         pline("%s voice booms:  \"How darest thou harm my servant!\"",
  616.             s_suffix(a_gname_at(ax, ay)));
  617.         break;
  618.     default:
  619.         pline("%s roars:  \"Thou dost profane my shrine!\"",
  620.             a_gname_at(ax, ay));
  621.         break;
  622.     }
  623.  
  624.     buzz(-10-(AD_ELEC-1), 6, x, y, sgn(tbx), sgn(tby)); /* bolt of lightning */
  625.     exercise(A_WIS, FALSE);
  626. }
  627.  
  628. void
  629. angry_priest()
  630. {
  631.     register struct monst *priest;
  632.  
  633.     if(priest = findpriest(temple_occupied(u.urooms)))
  634.         wakeup(priest);
  635. }
  636.  
  637. #endif /* OVLB */
  638.  
  639. /*priest.c*/
  640.